#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore>
#include <QtGui>
#include <QFileSystemModel>
#include <QLabel>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include "utility.h"

using namespace cv;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

    QStringList nameFilter;
    nameFilter << "*.png" << "*.jpg" << "*.gif";
    ui->setupUi(this);
    QString sPath="/home";
    dirmodel = new QFileSystemModel(this);
    dirmodel->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Files );
    dirmodel->setNameFilters(nameFilter);
    dirmodel->setNameFilterDisables(false);
    dirmodel->setRootPath(sPath);
    ui->TVFolder->setModel(dirmodel);
    setvis();
//    ui->BTProcess->setVisible(0);
    update();

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setclass(int x, int y)
{
    if (x==1)
    {
        ui->Re_11->setVisible(1);
        ui->Re_21->setVisible(0);
        ui->Re_31->setVisible(0);
    }
    if (x==2)
    {
        ui->Re_11->setVisible(0);
        ui->Re_21->setVisible(1);
        ui->Re_31->setVisible(0);
    }
    if (y==3)
    {
        ui->Re_11->setVisible(0);
        ui->Re_21->setVisible(0);
        ui->Re_31->setVisible(1);
    }
    if (y==1)
    {
        ui->Re_12->setVisible(1);
        ui->Re_22->setVisible(0);
        ui->Re_32->setVisible(0);
    }
    if (y==2)
    {
        ui->Re_12->setVisible(0);
        ui->Re_22->setVisible(1);
        ui->Re_32->setVisible(0);
    }
    if (y==3)
    {
        ui->Re_12->setVisible(0);
        ui->Re_22->setVisible(0);
        ui->Re_32->setVisible(1);
    }
    update();
}

void MainWindow::setvis()
{
    ui->Re_12->setVisible(0);
    ui->Re_22->setVisible(0);
    ui->Re_32->setVisible(0);
    ui->Re_11->setVisible(0);
    ui->Re_21->setVisible(0);
    ui->Re_31->setVisible(0);
    update();
}


void MainWindow::on_TVFolder_doubleClicked(const QModelIndex &index)
{
    if (!dirmodel->fileInfo(index).isFile()) return;
    QString sPath = dirmodel->fileInfo(index).absoluteFilePath();
    qDebug()<<sPath;
    Path = sPath;
    ui->_lbOriginalImage->setPixmap(QPixmap( sPath) );
    //image->show();
    update();



    Utility tool = Utility();
    //read image and convert to binary;
    cv::Mat colorImage  = cv::imread(Path.toLocal8Bit().data());

    cv::Mat binaryImage = tool.convertToBinary(colorImage);

    //
    cv::Mat showBinaryImage = tool.convertToBinary(colorImage);

    QImage img = QImage((uchar*)showBinaryImage.data, showBinaryImage.cols, showBinaryImage.rows, QImage::Format_Indexed8);
    ui->_lbBinaryImage->setPixmap(QPixmap::fromImage(img));


 //   cv::imshow("Binary", binaryImage);

    vector<Point> contour = tool.findContour(binaryImage);

    QString contourCoordinates = "";
    for (int i = 0; i < contour.size(); ++i) {
        Point point = contour[i];
        contourCoordinates += "(" + QString::number(point.x) +"." + QString::number(point.y) +")";
    }
    ui->_pteCoordinate->clear();
    ui->_pteCoordinate->appendPlainText(contourCoordinates);

    int windowSize = 99;
    vector<double> lcs = tool.obtainingLCS(contour, windowSize);
    vector<double> normalizedLcs = tool.linearAligment(lcs);

    _testGesture = normalizedLcs;

    QVector<double> lcsYValue;
    QVector<double> lcsXValue;
    double lcsYMax = 0;
    for (int index = 0; index < lcs.size(); ++index) {
        lcsYValue.push_back(lcs[index]);
        lcsXValue.push_back(index);
        if(lcsYMax < lcs[index]){
            lcsYMax = lcs[index];
        }
    }
    //Draw graph
    ui->GPContour_2->addGraph();
    ui->GPContour_2->xAxis->setRange(0,lcsYValue.size());
    ui->GPContour_2->yAxis->setRange(0,lcsYMax + lcsYMax/20);
    ui->GPContour_2->xAxis->setLabel("Index");
    ui->GPContour_2->yAxis->setLabel("h[index]");
    ui->GPContour_2->graph(0)->setData(lcsXValue,lcsYValue);
    ui->GPContour_2->replot();


    QVector<double> normalizedLcsYValue;
    QVector<double> normalizedLcsXValue;
    for (int index = 0; index < normalizedLcs.size(); ++index) {
        normalizedLcsYValue.push_back(normalizedLcs[index]);
        normalizedLcsXValue.push_back(index);
    }
    //Draw graph
    ui->GPContour->addGraph();
    ui->GPContour->xAxis->setRange(0,normalizedLcsYValue.size());
    ui->GPContour->yAxis->setRange(0,5);
    ui->GPContour->xAxis->setLabel("Index");
    ui->GPContour->yAxis->setLabel("h[index]");
    ui->GPContour->graph(0)->setData(normalizedLcsXValue,normalizedLcsYValue);
    ui->GPContour->replot();

    //do with sPath here
}

void MainWindow::on_TVFolder_clicked(const QModelIndex &index)
{
    if (!dirmodel->fileInfo(index).isFile()) return;
    QString sPath = dirmodel->fileInfo(index).absoluteFilePath();
    qDebug()<<sPath;
    Path = sPath;


    ui->_lbOriginalImage->setPixmap( QPixmap(sPath) );
    //image->show();
    update();
    //do with sPath here
}

//void MainWindow::on_BTProcess_clicked()
//{

//    Utility tool = Utility();
//    //read image and convert to binary;
//    cv::Mat colorImage  = cv::imread(Path.toLocal8Bit().data());

//    cv::Mat binaryImage = tool.convertToBinary(colorImage);

//    cv::imshow("Binary", binaryImage);

//    vector<Point> contour = tool.findContour(binaryImage);

//    QString contourCoordinates = "";
//    for (int i = 0; i < contour.size(); ++i) {
//        Point point = contour[i];
//        contourCoordinates += "(" + QString::number(point.x) +"." + QString::number(point.y) +")";
//    }
//    ui->_pteCoordinate->clear();
//    ui->_pteCoordinate->appendPlainText(contourCoordinates);

//    int windowSize = 99;
//    vector<double> lcs = tool.obtainingLCS(contour, windowSize);
//    vector<double> normalizedLcs = tool.linearAligment(lcs);

//    _testGesture = normalizedLcs;

//    QVector<double> lcsYValue;
//    QVector<double> lcsXValue;
//    double lcsYMax = 0;
//    for (int index = 0; index < lcs.size(); ++index) {
//        lcsYValue.push_back(lcs[index]);
//        lcsXValue.push_back(index);
//        if(lcsYMax < lcs[index]){
//            lcsYMax = lcs[index];
//        }
//    }
//    //Draw graph
//    ui->GPContour_2->addGraph();
//    ui->GPContour_2->xAxis->setRange(0,lcsYValue.size());
//    ui->GPContour_2->yAxis->setRange(0,lcsYMax + lcsYMax/20);
//    ui->GPContour_2->xAxis->setLabel("Index");
//    ui->GPContour_2->yAxis->setLabel("h[index]");
//    ui->GPContour_2->graph(0)->setData(lcsXValue,lcsYValue);
//    ui->GPContour_2->replot();


//    QVector<double> normalizedLcsYValue;
//    QVector<double> normalizedLcsXValue;
//    for (int index = 0; index < normalizedLcs.size(); ++index) {
//        normalizedLcsYValue.push_back(normalizedLcs[index]);
//        normalizedLcsXValue.push_back(index);
//    }
//    //Draw graph
//    ui->GPContour->addGraph();
//    ui->GPContour->xAxis->setRange(0,normalizedLcsYValue.size());
//    ui->GPContour->yAxis->setRange(0,5);
//    ui->GPContour->xAxis->setLabel("Index");
//    ui->GPContour->yAxis->setLabel("h[index]");
//    ui->GPContour->graph(0)->setData(normalizedLcsXValue,normalizedLcsYValue);
//    ui->GPContour->replot();


//}

void MainWindow::on__btnLoadRefGesture_clicked()
{
    Utility tool = Utility();
    QString path1 = QDir::currentPath() + "/ref1.jpg";
    ui->_lbRefImage1->setPixmap(QPixmap(path1).scaled(QSize(160,120),Qt::KeepAspectRatio));

    // caculate lcs vector
    cv::Mat colorImage  = cv::imread(path1.toLocal8Bit().data());
    cv::Mat binaryImage = tool.convertToBinary(colorImage);
    vector<Point> contour = tool.findContour(binaryImage);
    int windowSize = 99;
    vector<double> lcs = tool.obtainingLCS(contour, windowSize);
    vector<double> normalizedLcs = tool.linearAligment(lcs);
    _refGesture1 = normalizedLcs;

    // draw graph
    QVector<double> normalizedLcsYValue;
    QVector<double> normalizedLcsXValue;
    for (int index = 0; index < normalizedLcs.size(); ++index) {
        normalizedLcsYValue.push_back(normalizedLcs[index]);
        normalizedLcsXValue.push_back(index);
    }
    ui->_qpRefContour1->addGraph();
    ui->_qpRefContour1->xAxis->setRange(0,normalizedLcsYValue.size());
    ui->_qpRefContour1->yAxis->setRange(0,5);
    ui->_qpRefContour1->xAxis->setLabel("Index");
    ui->_qpRefContour1->yAxis->setLabel("h[index]");
    ui->_qpRefContour1->graph(0)->setData(normalizedLcsXValue,normalizedLcsYValue);
    ui->_qpRefContour1->replot();




    QString path2 = QDir::currentPath() + "/ref2.jpg";
    ui->_lbRefImage2->setPixmap(QPixmap(path2).scaled(QSize(160,120),Qt::KeepAspectRatio));

    // caculate lcs vector
    colorImage  = cv::imread(path2.toLocal8Bit().data());
    binaryImage = tool.convertToBinary(colorImage);
    contour = tool.findContour(binaryImage);
    lcs = tool.obtainingLCS(contour, windowSize);
    normalizedLcs = tool.linearAligment(lcs);
    _refGesture2 = normalizedLcs;
    normalizedLcsYValue.clear();
    normalizedLcsXValue.clear();
    for (int index = 0; index < normalizedLcs.size(); ++index) {
        normalizedLcsYValue.push_back(normalizedLcs[index]);
        normalizedLcsXValue.push_back(index);
    }

    // draw graph
    ui->_qpRefContour2->addGraph();
    ui->_qpRefContour2->xAxis->setRange(0,normalizedLcsYValue.size());
    ui->_qpRefContour2->yAxis->setRange(0,5);
    ui->_qpRefContour2->xAxis->setLabel("Index");
    ui->_qpRefContour2->yAxis->setLabel("h[index]");
    ui->_qpRefContour2->graph(0)->setData(normalizedLcsXValue,normalizedLcsYValue);
    ui->_qpRefContour2->replot();



    QString path3 = QDir::currentPath() + "/ref3.jpg";
    ui->_lbRefImage3->setPixmap(QPixmap(path3).scaled(QSize(160,120),Qt::KeepAspectRatio));

    // caculate lcs vector
    colorImage  = cv::imread(path3.toLocal8Bit().data());
    binaryImage = tool.convertToBinary(colorImage);
    contour = tool.findContour(binaryImage);
    lcs = tool.obtainingLCS(contour, windowSize);
    normalizedLcs = tool.linearAligment(lcs);
    _refGesture3 = normalizedLcs;
    normalizedLcsYValue.clear();
    normalizedLcsXValue.clear();
    for (int index = 0; index < normalizedLcs.size(); ++index) {
        normalizedLcsYValue.push_back(normalizedLcs[index]);
        normalizedLcsXValue.push_back(index);
    }

    // draw graph
    ui->_qpRefContour3->addGraph();
    ui->_qpRefContour3->xAxis->setRange(0,normalizedLcsYValue.size());
    ui->_qpRefContour3->yAxis->setRange(0,5);
    ui->_qpRefContour3->xAxis->setLabel("Index");
    ui->_qpRefContour3->yAxis->setLabel("h[index]");
    ui->_qpRefContour3->graph(0)->setData(normalizedLcsXValue,normalizedLcsYValue);
    ui->_qpRefContour3->replot();

}


void MainWindow::on__btnClassify_clicked()
{
    Utility tool = Utility();
    double linearDiff1 = tool.findLinearBestMatching(_refGesture1, _testGesture);
    double nonLinearDiff1 = tool.findNonlinearBestMatching(_refGesture1, _testGesture);
    ui->_leLinearDifferent1->setText(QString::number(linearDiff1));
    ui->_leNonlinearDifferent1->setText(QString::number(nonLinearDiff1));


    double linearDiff2 = tool.findLinearBestMatching(_refGesture2, _testGesture);
    double nonLinearDiff2 = tool.findNonlinearBestMatching(_refGesture2, _testGesture);
    ui->_leLinearDifferent2->setText(QString::number(linearDiff2));
    ui->_leNonlinearDifferent2->setText(QString::number(nonLinearDiff2));


    double linearDiff3 = tool.findLinearBestMatching(_refGesture3, _testGesture);
    double nonLinearDiff3 = tool.findNonlinearBestMatching(_refGesture3, _testGesture);
    ui->_leLinearDifferent3->setText(QString::number(linearDiff3));
    ui->_leNonlinearDifferent3->setText(QString::number(nonLinearDiff3));


    int x=0;int y=0;
    if (linearDiff1 == qMin(linearDiff1,qMin(linearDiff2,linearDiff3))) x=1;
    if (linearDiff2 == qMin(linearDiff1,qMin(linearDiff2,linearDiff3))) x=2;
    if (linearDiff3 == qMin(linearDiff1,qMin(linearDiff2,linearDiff3))) x=3;
    if (nonLinearDiff1 == qMin(nonLinearDiff1,qMin(nonLinearDiff2,nonLinearDiff3))) y=1;
    if (nonLinearDiff2 == qMin(nonLinearDiff1,qMin(nonLinearDiff2,nonLinearDiff3))) y=2;
    if (nonLinearDiff3 == qMin(nonLinearDiff1,qMin(nonLinearDiff2,nonLinearDiff3))) y=3;
    setclass(x,y);
}


